package com.book.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.book.exception.BusinessException;
import com.book.model.dto.*;
import com.book.model.entity.Books;
import com.book.model.entity.Campus;
import com.book.model.entity.PointsRecords;
import com.book.model.entity.User;
import com.book.mapper.UserMapper;
import com.book.model.vo.UserVO;
import com.book.service.CampusService;
import com.book.service.PointsRecordsService;
import com.book.service.SmsService;
import com.book.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.book.util.JwtUtil;
import io.swagger.annotations.ApiKeyAuthDefinition;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * <p>
 * 账号表 服务实现类
 * </p>
 *
 * @author auto
 * @since 2025-04-02 06:38:55
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private PointsRecordsService pointsRecordsService;

    @Autowired
    private CampusService campusService;

    @Autowired
    private SmsService smsService;

    @Override
    public User loginByUserNameAndPassword(AdminLoginDTO dto) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserName, dto.getAdminName());
        User admin = this.getOne(queryWrapper);
        //检验密码
        if(!admin.getPassword().equals(dto.getPassword())){
            throw new BusinessException("密码错误，请重新输入！！");
        }
        return admin;
    }

    @Override
    public User loginByWx(WxLoginDTO code) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getWechatOpenid, code.getWechatOpenid());
        User user = this.getOne(queryWrapper);
        boolean isNew = false;
        if(user==null){
            user = new User();
            isNew = true;
            user.setPoints(100L);
            user.setCreateTime(new Date());
        }
        user.setWechatOpenid(code.getWechatOpenid());
        user.setCity(code.getCity());
        user.setCountry(code.getCountry());
        user.setProvince(code.getProvince());
        user.setNickName(code.getNickName());
        this.saveOrUpdate(user);

        if(isNew){
            PointsRecords pointsRecords = new PointsRecords();
            pointsRecords.setUserId(user.getUserId());
            pointsRecords.setRecordsType(0);
            pointsRecords.setPointsAmount(100L);
            pointsRecords.setDescription("注册奖励");
            pointsRecords.setCreateTime(new Date());
            pointsRecordsService.save(pointsRecords);
        }
        return user;
    }

    @Override
    public UserVO getUserById(String id) {
        User user = this.getById(id);
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user,userVO);
        if(StringUtils.isNotBlank(user.getCampusId())){
            Campus campus = campusService.getById(user.getCampusId());
            userVO.setCampusName(campus.getCampusName());
            userVO.setUniverId(campus.getUniverId());
        }
        return userVO;
    }

    @Override
    public boolean bindPhone(BindPhoneDTO dto) {
        //校验验证码是否正确
        smsService.checkCode(dto.getPhone(),dto.getCode());
        User user =  this.getById(dto.getUserId());
        user.setPhone(dto.getPhone());
        return this.updateById(user);
    }

    @Override
    public boolean sendCode(String phone) {
        //校验手机号是否存在
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPhone,phone);
        List<User> userList = this.list(queryWrapper);
        if(CollectionUtils.isNotEmpty(userList)){
            throw new BusinessException("手机号重复，请更换手机号绑定");
        }
        return smsService.sendCode(phone);
    }

    @Override
    public boolean pointsGive(PointsGiveDTO dto) {

        //检查用户是否存在
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPhone,dto.getPhone());
        List<User> userList = this.list(queryWrapper);
        if(CollectionUtils.isEmpty(userList)){
            throw new BusinessException("用户不存在或者未进行手机号认证");
        }

        //检查积分是否足够
        User user = this.getById(dto.getUserId());
        if(user.getPoints()<dto.getPoints()){
            throw new BusinessException("您当前积分为："+user.getPoints()+"，积分不足，请修改转让积分数量");
        }

        User getUser = userList.get(0);
        //进行积分转让
        user.setPoints(user.getPoints()-dto.getPoints());
        getUser.setPoints(getUser.getPoints()+dto.getPoints());
        this.updateById(user);
        this.updateById(getUser);
        return true;
    }

    @Override
    public Page<User> getListByPage(UserQueryPageDTO dto) {
        Page<User> page = new Page<>(dto.getPage(),dto.getSize());
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(dto.getUsername())) {
            queryWrapper.and(wrapper -> wrapper
                    .like(User::getUserName, dto.getUsername())
                    .or()
                    .like(User::getPhone, dto.getUsername())
                    .or()
                    .like(User::getNickName, dto.getUsername())
            );
        }
        if(dto.isAdmin()){
            queryWrapper.isNotNull(User::getPassword);
        }else{
            queryWrapper.isNotNull(User::getWechatOpenid);
        }
        Page<User> userPage = this.page(page,queryWrapper);
        return userPage;
    }

    @Override
    public boolean resetPassword(AdminResetDTO dto) {
        //校验短信验证码
        smsService.checkCode(dto.getTel(),dto.getCode());
        //修改用户密码
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPhone,dto.getTel());
        queryWrapper.eq(User::getPassword,dto.getOldPassword());
        User user = this.getOne(queryWrapper);
        if(user==null){
            throw new BusinessException("旧密码或手机号错误，请重新输入！！");
        }
        user.setPassword(dto.getNewPassword());
        return this.updateById(user);
    }

    @Override
    public User addOrUpdateUser(User user) {
        if(StringUtils.isNotBlank(user.getUserId())){
            user.setCreateTime(new Date());
        }
        this.saveOrUpdate(user);
        return user;
    }
}
